import 'dart:math';
import 'package:flutter/material.dart';
import 'layer.dart';

class EllipseLayer extends Layer {
  Offset center;
  double width, height, angle;

  int? draggingHandle; // 0–3 控制点，4 中心
  Offset? startDrag;

  EllipseLayer(this.center, this.width, this.height, this.angle);

  @override
  bool hitTest(Offset p) {
    // 扩大检测区域的系数（1.0表示不扩大，值越大检测区域越大）
    const hitTestScale = 1.2;

    // 计算点到椭圆中心的相对坐标
    final dx = p.dx - center.dx;
    final dy = p.dy - center.dy;

    // 计算旋转后的坐标（反向旋转）
    final ca = cos(-angle);
    final sa = sin(-angle);
    final x = dx * ca - dy * sa;
    final y = dx * sa + dy * ca;

    // 椭圆半轴长度（扩大检测区域）
    final a = width / 2 * hitTestScale;
    final b = height / 2 * hitTestScale;

    // 椭圆方程检测（扩大后的区域）
    return (x * x) / (a * a) + (y * y) / (b * b) <= 1;
  }

  List<Offset> _handles() {
    final w = width / 2, h = height / 2;
    final pts = [
      Offset(0, -h),
      Offset(w, 0),
      Offset(0, h),
      Offset(-w, 0),
    ];
    return pts.map((p) {
      final rx = p.dx * cos(angle) - p.dy * sin(angle);
      final ry = p.dx * sin(angle) + p.dy * cos(angle);
      return center + Offset(rx, ry);
    }).toList();
  }

  @override
  void paint(Canvas canvas, Size size) {
    Color color = selected ? Colors.orange : Colors.white;
    final stroke = Paint()
      ..color = color
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1;
    canvas.save();
    canvas.translate(center.dx, center.dy);
    canvas.rotate(angle);
    canvas.drawOval(
      Rect.fromCenter(center: Offset.zero, width: width, height: height),
      stroke,
    );
    canvas.restore();

    final hPaint = Paint()..color = color;
    for (final h in _handles()) {
      canvas.drawRect(Rect.fromCenter(center: h, width: 8, height: 8), hPaint);
    }
    canvas.drawRect(
        Rect.fromCenter(center: center, width: 8, height: 8), hPaint);
  }

  @override
  void onPanStart(Offset localPos, Size boundary) {
    final hs = _handles();
    for (int i = 0; i < hs.length; i++) {
      if ((hs[i] - localPos).distance < hitRadius) {
        draggingHandle = i;
        startDrag = localPos;
        return;
      }
    }
    if ((center - localPos).distance < hitRadius) {
      draggingHandle = 4;
      startDrag = localPos;
    }
  }

  @override
  void onPanUpdate(Offset localPos, Size boundary) {
    if (draggingHandle == null || startDrag == null) return;
    final hs = _handles();
    final np = localPos;
    if (draggingHandle == 1 || draggingHandle == 3) {
      final P = hs[draggingHandle!], Q = hs[draggingHandle == 1 ? 3 : 1];
      final v1 = P - Q, v2 = np - Q;
      final scale = v2.distance / v1.distance;
      final dA = atan2(v2.dy, v2.dx) - atan2(v1.dy, v1.dx);
      width = (width * scale).clamp(30, boundary.width);
      angle += dA;
    } else if (draggingHandle == 0 || draggingHandle == 2) {
      final P = hs[draggingHandle!], Q = hs[draggingHandle == 0 ? 2 : 0];
      final v1 = P - Q, v2 = np - Q;
      final scale = v2.distance / v1.distance;
      final dA = atan2(v2.dy, v2.dx) - atan2(v1.dy, v1.dx);
      height = (height * scale).clamp(30, boundary.height);
      angle += dA;
    } else if (draggingHandle == 4) {
      final delta = np - startDrag!;
      final halfW = width / 2, halfH = height / 2;
      double nx = (center.dx + delta.dx).clamp(halfW, boundary.width - halfW);
      double ny = (center.dy + delta.dy).clamp(halfH, boundary.height - halfH);
      center = Offset(nx, ny);
    }
    startDrag = np;
  }

  @override
  void onPanEnd(Size boundary) {
    draggingHandle = null;
    selected = false;
  }

  @override
  double getMetric() {
    // 椭圆面积 = πab
    final a = width / 2, b = height / 2;
    return pi * a * b;
  }
}
